<?php

if (!defined('TOBBIVM'))
	header('location:/template/notrepassing.php');
/**
 * This file is part of TobbiVMShop.
 *
 * TobbiVMShop is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * TobbiVMShop is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with TobbiVMShop.  If not, see <http://www.gnu.org/licenses/>.
 */

/**
 * Validate Inputs for wrong Characters
 *
 * Original from: @author     Andreas Skodzek <webmaster@phpbuddy.eu>
 *                @link       http://www.phpbuddy.eu
 *                @copyright  2008 Andreas Skodzek
 *                @license    GNU Public License <http://www.gnu.org/licenses/gpl.html>
 *                @version    v1.0 released 03.03.2008
 *
 * @version    $Id$
 * @package    TobbiVM-Shop
 * @copyright  Copyright (C) 2012
 * @author     Norbert Gebert
 * @license    GPL3
 */
class validate
{

	/**
	 * @var string Search pattern for Numbers
	 */
	protected $sample_number = '/^\d+$/';

	/**
	 * @var string Search pattern for Zipcode (German)
	 */
	protected $sample_zip = '/^[0-9]{5}$/';

	/**
	 * @var string Search pattern for Date-Format (German)
	 */
	protected $sample_date = '/^[0-9]{1,2}(\.|\/|\-){1}[0-9]{1,2}(\.|\/|\-){1}[0-9]{4}$/';

	/**
	 * @var string Search pattern for Phonnumber
	 */
	protected $sample_phone = '/^[0-9\+\(\)\/\-\s]+$/';

	/**
	 * @var string Search pattern for amount of money
	 */
	protected $sample_money = '/^([1-9]{1}[0-9]{0,2}((\.)?[0-9]{3})*((\.|\,)?[0-9]{0,2})?|[1-9]{1}[0-9]{0,}((\.|\,)?[0-9]{0,2})?|0((\.|\,)?[0-9]{0,2})?|((\.|\,)?[0-9]{1,2})?)$/';

	/**
	 * @var string SSearch pattern for single Words
	 */
	protected $sample_word = '/^[a-zA-ZäÄöÖüÜß\xc0-\xc2\xc8-\xcf\xd2-\xd4\xd9-\xdb\xe0-\xe2\xe8-\xef\xf2-\xf4\xf9-\xfb\x9f\xff\']+$/';

	/**
	 * @var string Search pattern for Names
	 */
	protected $sample_name = '/^([a-zA-ZäÄöÖüÜß\xc0-\xc2\xc8-\xcf\xd2-\xd4\xd9-\xdb\xe0-\xe2\xe8-\xef\xf2-\xf4\xf9-\xfb\x9f\xff\.\'\-_]?(\s)?)+$/';

	/**
	 * @var string Search pattern for Emailadress (create at the Constructor)
	 */
	protected $sample_email = '';

	/**
	 * @var string Search pattern for Internetadresses
	 */
	protected $sample_url = '/^(http|https)\:\/\/([a-zA-Z0-9\.\-]+(\:[a-zA-Z0-9\.&%\$\-]+)*@)?((25[0-5]|2[0-4][0-9]|[0-1]{1}[0-9]{2}|[1-9]{1}[0-9]{1}|[1-9])\.(25[0-5]|2[0-4][0-9]|[0-1]{1}[0-9]{2}|[1-9]{1}[0-9]{1}|[1-9]|0)\.(25[0-5]|2[0-4][0-9]|[0-1]{1}[0-9]{2}|[1-9]{1}[0-9]{1}|[1-9]|0)\.(25[0-5]|2[0-4][0-9]|[0-1]{1}[0-9]{2}|[1-9]{1}[0-9]{1}|[0-9])|([a-zA-Z0-9\-]+\.)*[a-zA-Z0-9\-]+\.[a-zA-Z]{2,6})(\:[0-9]+)?(\/[a-zA-Z0-9\.\,\?\'\\/\+&%\$#\=~_\-@]*)*$/';

	/**
	 * @var array Forbidden phrases that indicate SQL-injection
	 */
	protected $sql_injection = array('delete from',
	 'drop table',
	 'insert into',
	 'select from',
	 'select into',
	 'update set');

	/**
	 * @var array Forbidden phrases that indicate email-injection
	 */
	protected $email_injection = array('bcc:',
	 'boundary',
	 'cc:',
	 'content-transfer-encoding:',
	 'content-type:',
	 'mime-version:',
	 'subject:');

	/**
	 * @var array Search for pattern variables to clean up
	 */
	protected $clear_sample = array('/(\r\n)|(\r)/m',
	 '/(\n){3,}/m',
	 '/\s{3,}/m',
	 '/(.)\\1{15,}/im');

	/**
	 * @var array Substitute for variables to be cleaned
	 */
	protected $clear_replacement = array('\n',
	 '\n\n',
	 //' ',
	 '\\1');

	/**
	 * @var array Taking the wrong fields
	 */
	protected $field_error = array();

	/**
	 * Error message for incorrect format
	 */
	private $fieldErrorFormat;

	/**
	 * Error message for too short a field-content
	 */
	private $fieldErrorToShort;

	/**
	 * Error message for too short a field-content
	 */
	private $fieldErrorToLong;

	/**
	 * Error message for too date format
	 */
	private $fieldErrorDate;

	/**
	 * Error message for possible injection
	 */
	private $fieldErrorInjection;

	/**
	 * Konstruktor
	 */
	public function __construct()
	{
		// Search pattern for email validation assemble
		$nonascii = '\x80-\xff';
		$nqtext = '[^\\\\' . $nonascii . '\015\012\"]';
		$qchar = '\\\\[^' . $nonascii . ']';
		$normuser = '[a-zA-Z0-9][a-zA-Z0-9_.-]*';
		$quotedstring = '\"(?:' . $nqtext . '|' . $qchar . ')+\"';
		$user_part = '(?:' . $normuser . '|' . $quotedstring . ')';
		$dom_mainpart = '[a-zA-Z0-9][a-zA-Z0-9._-]*\\.';
		$dom_subpart = '(?:[a-zA-Z0-9][a-zA-Z0-9._-]*\\.)*';
		$dom_tldpart = '[a-zA-Z]{2,5}';
		$domain_part = $dom_subpart . $dom_mainpart . $dom_tldpart;
		$pattern = $user_part . '\@' . $domain_part;
		$this->sample_email = '/^{' . $pattern . '}$/';

		$this->fieldErrorFormat = _('The entry has the wrong format.');
		$this->fieldErrorToShort = _('The input is too short.');
		$this->fieldErrorToLong = _('The input is too long.');
		$this->fieldErrorDate = _('The date entered is not valid.');
		$this->fieldErrorInjection = _('The input may contain a malicious expression.');
	}

	/**
	 * Method to clean up of variables
	 *
	 * @param  mixed  $input User input
	 * @return mixed  returns cleared variable
	 */
	final private function clear(&$input)
	{
		if (get_magic_quotes_gpc())
		{
			$input = stripslashes($input);
		}
		$input = trim($input);
		$input = preg_replace($this->clear_sample, $this->clear_replacement, $input);
		$input = wordwrap($input, 45, ' ', true);
		return $input;
	}

	/**
	 * Method to check for Injections
	 *
	 * @param  mixed  $input User input
	 * @param  string $label Designation of the field
	 *                 - is needed for the error message
	 * @return mixed  returns cleared variable
	 */
	final private function injection(&$input, $label)
	{
		// Check for potential SQL Injections
		foreach ($this->sql_injection as $injection)
		{
			if (preg_match('/{$injection}/i', $input))
			{
				message::setErrorRow($label . ': ' . self::fieldErrorInjection);
				$input = '';
			}
		}

		// Check for potential email injections
		foreach ($this->email_injection as $injection)
		{
			if (preg_match('/{$injection}/i', $input))
			{
				message::setErrorRow($label . ': ' . self::fieldErrorInjection);
				$input = '';
			}
		}
		return $input;
	}

	/**
	 * Checks the input to a valid number
	 *
	 * @param  integer $input User input
	 * @param  string  $label $label Designation of the field
	 *                  - is needed for the error message
	 * @return mixed   returns cleared variable or FALSE
	 */
	final public function testNumber(&$input, $label)
	{
		self::clear($input);
		self::injection($input, $label);
		if (preg_match($this->sample_number, $input))
		{
			return $input;
		}
		else
		{
			message::setErrorRow($label . ': ' . $this->fieldErrorFormat);
			return false;
		}
	}

	/**
	 * Checks the input to a valid ZIP code
	 *
	 * @param  integer $input User input
	 * @param  string  $label Designation of the field
	 *                  - is needed for the error message
	 * @return mixed   returns cleared variable or FALSE
	 */
	final public function testZip(&$input, $label)
	{
		self::clear($input);
		self::injection($input, $label);
		if (preg_match($this->sample_zip, $input))
		{
			return $input;
		}
		else
		{
			message::setErrorRow($label . ': ' . $this->fieldErrorFormat);
			return false;
		}
	}

	/**
	 * Checks the input to a valid date
	 *
	 * @param  mixed  $input User input
	 * @param  string $label $label Designation of the field
	 *                  - is needed for the error message
	 * @param  string $separator Is broken at the date separator
	 * @return mixed  returns cleared variable or FALSE
	 */
	final public function pruefeDatum(&$input, $label, $separator)
	{
		self::clear($input);
		self::injection($input, $label);
		if (preg_match($this->sample_date, $input))
		{
			$date_elements = explode($separator, $input);
			// Check the validity of date
			if (checkdate($date_elements[1], $date_elements[0], $date_elements[2]))
			{
				return $input;
			}
			else
			{
				message::setErrorRow($label . ': ' . self::fieldErrorDate);
				return false;
			}
		}
		else
		{
			message::setErrorRow($label . ': ' . self::fieldErrorDate);
			return false;
		}
	}

	/**
	 * Checks the input to a valid phone number
	 *
	 * @param  mixed  $input User input
	 * @param  string $label Designation of the field
	 *                  - is needed for the error message
	 * @return mixed  returns cleared variable or FALSE
	 */
	final public function testPhonenumber(&$input, $label)
	{
		self::clear($input);
		self::injection($input, $label);
		if (preg_match($this->sample_phone, $input))
		{
			return $input;
		}
		else
		{
			message::setErrorRow($label . ': ' . $this->fieldErrorFormat);
			return false;
		}
	}

	/**
	 * Checks the input to a valid monetary amount
	 *
	 * @param  mixed  $input User input
	 * @param  string $label Designation of the field
	 *                  - is needed for the error message
	 * @return mixed  returns cleared variable or FALSE
	 */
	final public function testMoney(&$input, $label)
	{
		self::clear($input);
		self::injection($input, $label);
		if (preg_match($this->sample_money, $input))
		{
			return $input;
		}
		else
		{
			message::setErrorRow($label . ': ' . $this->fieldErrorFormat);
			return false;
		}
	}

	/**
	 * Checks the input to a valid word
	 *
	 * @param  string  $input User input
	 * @param  string  $label Designation of the field
	 *                  - is needed for the error message
	 * @param  integer $min_length Minimum length of input
	 * @param  integer $max_length Maximum length of input
	 * @return mixed   returns cleared variable or FALSE
	 */
	final public function testWord(&$input, $label, $min_length = 999, $max_length = 999)
	{
		self::clear($input);
		self::injection($input, $label);
		// test of Minimum lenght - if set!
		if ($min_length != 999)
		{
			if (strlen($input) < $min_length)
			{
				message::setErrorRow($label . ': ' . self::fieldErrorToShort);
				return false;
			}
		}
		// test of Maximum lenght - if set!
		if ($max_length != 999)
		{
			if (strlen($input) > $max_length)
			{
				message::setErrorRow($label . ': ' . self::fieldErrorToLong);
				return false;
			}
		}
		// Check the search pattern
		if (preg_match($this->sample_word, $input))
		{
			return $input;
		}
		else
		{
			message::setErrorRow($label . ': ' . $this->fieldErrorFormat);
			return false;
		}
	}

	/**
	 * Checks the input to a valid name
	 *
	 * @param  string  $input User input
	 * @param  string  $label Designation of the field
	 *                  - is needed for the error message
	 * @param  integer $min_length Minimum length of input
	 * @param  integer $max_length Maximum length of input
	 * @return mixed   returns cleared variable or FALSE
	 */
	final public function testName(&$input, $label, $min_length = 999, $max_length = 999)
	{
		self::clear($input);
		self::injection($input, $label);
		// test of Maximum lenght - if set!
		if ($min_length != 999)
		{
			if (strlen($input) < $min_length)
			{
				message::setErrorRow($label . ': ' . $this->fieldErrorToShort);
				return false;
			}
		}
		// test of Maximum lenght - if set!
		if ($max_length != 999)
		{
			if (strlen($input) > $max_length)
			{
				message::setErrorRow($label . ': ' . self::fieldErrorToLong);
				return false;
			}
		}
		// Check the search pattern
		if (preg_match($this->sample_name, $input))
		{
			return $input;
		}
		else
		{
			message::setErrorRow($label . ': ' . $this->fieldErrorFormat);
			return false;
		}
	}

	/**
	 * Checks the input on possible injections in long text
	 *
	 * @param  string  $input User input
	 * @param  string  $label Designation of the field
	 *                  - is needed for the error message
	 * @param  integer $min_length Minimum length of input
	 * @param  integer $max_length Maximum length of input
	 * @return mixed   returns cleared variable or FALSE
	 */
	final public function testText(&$input, $label, $min_length = 999, $max_length = 999)
	{
		self::clear($input);
		self::injection($input, $label);
		// test of Maximum lenght - if set!
		if ($min_length != 999)
		{
			if (strlen($input) < $min_length)
			{
				message::setErrorRow($label . ': ' . $this->fieldErrorToShort);
				return false;
			}
		}
		// test of Maximum lenght - if set!
		if ($max_length != 999)
		{
			if (strlen($input) > $max_length)
			{
				message::setErrorRow($label . ': ' . $this->fieldErrorToLong);
				return false;
			}
		}
		return $input;
	}

	/**
	 * Prüft die Eingabe auf eine gültige Email-Adresse
	 *
	 * @param  string  $input User input
	 * @param  string  $label Designation of the field
	 *                  - is needed for the error message
	 * @return mixed   returns cleared variable or FALSE
	 */
	final public function testEmail(&$input, $label)
	{
		self::clear($input);
		self::injection($input, $label);
		// Test for Search pattern
		//if (preg_match($this->sample_email, $input))
		if (preg_match('/^[^\x00-\x20()<>@,;:\\".[\]\x7f-\xff]+(?:\.[^\x00-\x20()<>@,;:\\".[\]\x7f-\xff]+)*\@[^\x00-\x20()<>@,;:\\".[\]\x7f-\xff]+(?:\.[^\x00-\x20()<>@,;:\\".[\]\x7f-\xff]+)+$/i',
				$input))
		{
			return $input;
		}
		else
		{
			message::setErrorRow($label . ': ' . $this->fieldErrorFormat);
			return false;
		}
	}

	/**
	 * Prüft die Eingabe auf einen gültige Web-Adresse
	 *
	 * @param  string  $input User input
	 * @param  string  $label Designation of the field
	 *                  - is needed for the error message
	 * @return mixed   returns cleared variable or FALSE
	 */
	final public function testURL(&$input, $label)
	{
		self::clear($input);
		self::injection($input, $label);
		// Test for URL Prefix prüfen and possibly add
		if (strtolower(substr($input, 0, 7)) != 'http://' &&
			strtolower(substr($input, 0, 8)) != 'https://')
		{
			$input = 'http://' . $input;
		}
		// Test for Search pattern
		if (preg_match($this->sample_url, $input))
		{
			return $input;
		}
		else
		{
			message::setErrorRow($label . ': ' . $this->fieldErrorFormat);
			return false;
		}
	}

	/**
	 * Clean input from slashes, NULL-Bytes, decode and trim it
	 *
	 * @param  string $input    input to clean
	 * @return string cleared and trimmed input
	 */
	final public function cleanslash($input)
	{
		// Remove masking slashes
		if (get_magic_quotes_gpc())
		{
			$input = stripslashes($input);
		}
		// delete NULL-Bytes
		$input = preg_replace('#(&\#x*)([0-9A-F]+);*#iu', '\\1\\2;', $input);
		// decode
		$input = preg_replace('/&#x([a-f0-9]+);/mei', 'chr(0x\\1)', $input);
		// Trim
		$input = trim($input);
		return $input;
	}

	/**
	 * Returns the error array
	 *
	 * @return array Returns the array of error messages back
	 */
	final public function getError()
	{
		return $this->field_error;
	}

}

?>